package com.gregbugaj.gps;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import com.gregbugaj.gps.cmd.Command;
import com.gregbugaj.gps.transform.KMLTransformer;
import com.gregbugaj.gps.transform.Transformer;


public class GPSParser {
	private boolean bIsDataLoaded;
	private List<Command> lines;

	private Route route;

	public GPSParser(){
		lines=new ArrayList<Command>();
		route=new Route();
	}
	public void load(File input) throws IOException {
		BufferedReader reader=new BufferedReader(new FileReader(input));
		String out=null;
		while((out=reader.readLine())!=null){
			//Validate the format of the line
			if(!out.startsWith("$")){
				throw new IllegalArgumentException("Format of \""+out+"\" is illegal.");
			}
			String cmd=out.split(",")[0];
			if(cmd.startsWith("$PSRFTXTVersion")){
				continue;
			}

			String cmdString=out.substring(cmd.length()+1);
			Command command = CommandFactory.getCommand(cmd , cmdString);
			if(command!=null){
				lines.add(command);

			}
		}
		bIsDataLoaded=true;
	}


	public void parse() {
		if(!bIsDataLoaded){
			throw new IllegalStateException("Data has not been loaded yet");
		}

		List<RoutePoint> routePoints=new ArrayList<RoutePoint>();
		System.out.println("Route points ="+lines.size());
		//lines.size()
		boolean isFirstPoint=true;
		RoutePoint lastPoint=null;
		for(int i=0;i<lines.size();i++){
			Command ll=lines.get(i);	
			//Need to start with  CommandType.GPGLL 
			if(isFirstPoint && ll.getType()!=CommandType.GPGLL){
				while(i<lines.size()){
					i++;
					ll=lines.get(i);
					if(ll.getType()==CommandType.GPGLL){
						break;
					}
				}
			}

			HashMap<String, Object> result=ll.parse();		
			RoutePoint point=new RoutePoint();
			point.setLatitude((Latitude) result.get("latitude"));
			point.setLongitude((Longitude) result.get("longitude"));
			point.setTime((Date) result.get("time"));
			
			if(ll.getType() == CommandType.GPGLL && i<lines.size()-1){
				i++;
				Command vtg=lines.get(i);
				HashMap<String, Object> resultVTG= vtg.parse();
				point.setSpeedInKM((Double) resultVTG.get("speed"));
			}
			if(!point.validate()){
				continue;
			}
			
			//Make sure we are not storing idle points
			if(isFirstPoint){				
				routePoints.add(point);		
			}else{
				if(!lastPoint.equals(point)){
					routePoints.add(point);	
				}
			}
			lastPoint=point;
			isFirstPoint=false;
		}
		route.setPoints(routePoints);
	}
	
	/**
	 * Get loaded Route
	 * @return last parsed route
	 */
	public Route getRoute() {
		return route;
	}

	
	public static void main(String[] args) throws IOException {
		GPSParser app=new GPSParser();
		File in=new  File("C:/dev/java/workspace-seam/logs/LOG0005.log");
		app.load(in);
		app.parse();
		Route route=app.getRoute();
	/*
		System.out.println("Route distance="+route.getDistanceInKM());
		RoutePoint a=route.getPoints().get(0);
		RoutePoint b=route.getLast();
	*/
		
		Transformer transformer=new KMLTransformer();
		transformer.transform(route);
		System.out.println(transformer.getTransformed());
	}

}
